const { pool, data_url } = require('../database.js');

const getVideoList = async (request, response) => {
  try {
    const userId = request.query.user_id || 1; // 获取当前用户ID，默认为1
    const school_code = request.query.school_code || ''; // 获取当前学校代码，默认为0
    const limit = parseInt(10); // 确保 limit 是数字类型
    const newVideoLimit = Math.floor(limit * 0.3); // 30%的推荐位给予新视频或零互动视频

    // 1. 获取用户视频类型偏好的SQL
    // - 统计用户观看每种类型视频的次数和总观看时长
    // - watch_duration * watch_count 计算总观看时间权重
    // - 按总观看时长降序排序，优先考虑用户花费时间最多的类型
    const userTypePreferencesSql = `
      SELECT 
        v.video_type,                                          -- 视频类型
        COUNT(*) as type_count,                               -- 该类型视频的观看次数
        SUM(h.watch_duration * h.watch_count) as total_watch_time  -- 该类型的总观看时长
      FROM user_video_history h
      JOIN video_list v ON h.video_id = v.video_id
      WHERE h.user_id = ${userId}
      GROUP BY v.video_type
      ORDER BY total_watch_time DESC
    `;

    const [typePreferences] = await pool.execute(userTypePreferencesSql);
    const totalWatchTime = typePreferences.reduce((sum, p) => sum + p.total_watch_time, 0) || 1;
    const typeWeights = typePreferences.reduce((acc, p) => {
      acc[p.video_type] = (p.total_watch_time / totalWatchTime) * 2; // 类型权重最高2
      return acc;
    }, {});

    // 2. 获取相似用户的SQL
    // - 通过共同观看的视频来识别相似用户
    // - common_videos 表示共同观看的视频数量
    // - total_watch_time 用于进一步判断用户的观看投入度
    const similarUsersSql = `
      SELECT DISTINCT 
        h2.user_id,                                           -- 相似用户ID
        COUNT(*) as common_videos,                            -- 共同观看的视频数
        SUM(h2.watch_duration * h2.watch_count) as total_watch_time  -- 相似用户的总观看时长
      FROM user_video_history h1
      JOIN user_video_history h2 ON h1.video_id = h2.video_id
      WHERE h1.user_id = ${userId} 
        AND h2.user_id != ${userId}                          -- 排除用户自己
      GROUP BY h2.user_id
      HAVING common_videos >= 2                              -- 至少需要2个共同观看的视频
      ORDER BY total_watch_time DESC                         -- 按观看时长排序
      LIMIT 10                                               -- 取前10个最相似的用户
    `;

    const [similarUsers] = await pool.execute(similarUsersSql);
    const similarUserIds = similarUsers.map(u => u.user_id);
    const userIdList = similarUserIds.length ? similarUserIds : [userId];
    const userIdStr = userIdList.join(',');
    const typeStr = Object.keys(typeWeights).length ? Object.keys(typeWeights).join(',') : '0';
    const typeWeightValue = Object.values(typeWeights).length ? Math.max(...Object.values(typeWeights)) : 1;

    // 3. 获取热门视频推荐列表的SQL
    // - 计算视频的综合互动分数
    // - 考虑用户类型偏好
    // - 考虑时间衰减因子
    const hotVideoSql = `
      SELECT 
        v.*,                                                 -- 视频基本信息
        u.author_name,                                       -- 作者名称
        u.avatar_url,                                        -- 从 users 表获取作者头像
        EXISTS (
          SELECT 1 FROM friends f 
          WHERE f.user_id = ${userId} 
          AND f.friend_id = v.author_id
        ) as isFollowed,                                     -- 添加关注状态判断
        (
          CASE 
            WHEN (v.love_num + v.collect_num + v.comment_num + v.forward_num) = 0 
            THEN 0.1                                         -- 零互动视频给予基础分数
            ELSE (
              v.love_num * 3 +                               -- 点赞权重 3
              v.collect_num * 2 +                            -- 收藏权重 2
              v.comment_num * 1.5 +                          -- 评论权重 1.5
              v.forward_num +                                -- 转发权重 1
              COALESCE(
                (
                  SELECT SUM(watch_duration * watch_count)   -- 相似用户的观看时长权重
                  FROM user_video_history
                  WHERE video_id = v.video_id
                  AND user_id IN (${userIdStr})
                ), 0
              ) * 0.5
            )
          END *
          CASE 
            WHEN v.video_type IN (${typeStr})               -- 用户偏好的视频类型
            THEN ${typeWeightValue}                         -- 给予更高权重
            ELSE 1
          END
        ) / POWER(1.1, DATEDIFF(CURRENT_DATE, v.video_date)) as interaction_score,  -- 时间衰减因子
        (
          SELECT JSON_ARRAYAGG(                             -- 聚合弹幕信息为JSON数组
            JSON_OBJECT(
              'content', d.content,
              'time_point', d.time_point,
              'type', d.type,
              'color', d.color,
              'font_size', d.font_size,
              'id', d.danmaku_id
            )
          )
          FROM video_danmaku d
          WHERE d.video_id = v.video_id 
          AND d.is_blocked = 0                              -- 只获取未被屏蔽的弹幕
        ) as danmaku_list
      FROM video_list v
      LEFT JOIN users u ON v.author_id = u.user_id         -- 从 users 表中获取头像
      WHERE v.status = 1                                    -- 只获取正常状态的视频
      ${school_code ? 'AND v.school_code = ?' : ''}         -- 如果有学校代码则添加筛选
      AND v.video_id NOT IN (                               -- 排除用户已观看的视频
        SELECT video_id 
        FROM user_video_history 
        WHERE user_id = ${userId}
      )
      AND (
        v.video_type IN (${typeStr})                        -- 匹配用户喜欢的视频类型
        OR v.author_id IN (                                 -- 或匹配相似用户关注的作者
          SELECT DISTINCT author_id
          FROM video_list
          WHERE video_id IN (
            SELECT video_id
            FROM user_video_history
            WHERE user_id IN (${userIdStr})
          )
        )
      )
      AND (v.love_num + v.collect_num + v.comment_num + v.forward_num) > 0  -- 确保有基本互动
      ORDER BY interaction_score DESC                        -- 按综合分数排序
      LIMIT ${limit - newVideoLimit}                        -- 热门视频数量
    `;

    // 4. 获取新视频或零互动视频的SQL
    // - 专门为新视频设计的推荐逻辑
    // - 主要考虑发布时间
    const newVideoSql = `
      SELECT 
        v.*,                                                -- 视频基本信息
        u.author_name,                                      -- 作者名称
        u.avatar_url,                                       -- 从 users 表获取作者头像
        EXISTS (
          SELECT 1 FROM friends f 
          WHERE f.user_id = ${userId} 
          AND f.friend_id = v.author_id
        ) as isFollowed,                                    -- 添加关注状态判断
        1 / POWER(1.1, DATEDIFF(CURRENT_DATE, v.video_date)) as interaction_score,
        (
          SELECT JSON_ARRAYAGG(                            -- 聚合弹幕信息
            JSON_OBJECT(
              'content', d.content,
              'time_point', d.time_point,
              'type', d.type,
              'color', d.color,
              'font_size', d.font_size,
              'id', d.danmaku_id
            )
          )
          FROM video_danmaku d
          WHERE d.video_id = v.video_id 
          AND d.is_blocked = 0                             -- 未被屏蔽的弹幕
        ) as danmaku_list
      FROM video_list v
      LEFT JOIN users u ON v.author_id = u.user_id         -- 从 users 表中获取头像
      WHERE v.status = 1                                   -- 正常状态的视频
      ${school_code ? 'AND v.school_code = ?' : ''}        -- 如果有学校代码则添加筛选
      AND v.video_id NOT IN (                              -- 排除已观看
        SELECT video_id 
        FROM user_video_history 
        WHERE user_id = ${userId}
      )
      AND (v.love_num + v.collect_num + v.comment_num + v.forward_num) = 0  -- 零互动视频
      ORDER BY v.video_date DESC                           -- 按发布时间倒序
      LIMIT ${newVideoLimit}                               -- 新视频数量限制
    `;

    const [hotVideos] = await pool.execute(hotVideoSql, school_code ? [school_code] : []);
    const [newVideos] = await pool.execute(newVideoSql, school_code ? [school_code] : []);
    const results = [...hotVideos, ...newVideos];

    // 处理结果
    const processedResults = results.map(result => ({
      ...result,
      video_url: data_url + result.video_url,
      cover_url: result.cover_url ? data_url + result.cover_url : null,
      avatar_url: result.avatar_url ? data_url + result.avatar_url : null,
      danmaku_list: result.danmaku_list ? result.danmaku_list : [],
      interaction_score: parseFloat(result.interaction_score).toFixed(2),
      isFollowed: Boolean(result.isFollowed)  // 确保返回布尔值
    }));

    response.json({
      msg: 'success',
      code: "200",
      data: processedResults
    });

  } catch (error) {
    // 打印详细错误信息
    console.error('获取推荐视频失败:', error);
    console.error('错误详情:', {
      message: error.message,
      code: error.code,
      sqlState: error.sqlState,
      sqlMessage: error.sqlMessage
    });

    response.json({
      msg: '未知错误，联系管理员',
      code: "500",
      error: error.message
    });
  }
}

const recordHistory = async (request, response) => {
  try {
    const { video_id, watch_duration } = request.body;
    const { user_id } = request.query;

    const sql = `
      INSERT INTO user_video_history (user_id, video_id, watch_duration, watch_count, last_watch_time)
      VALUES (?, ?, ?, 1, NOW())
      ON DUPLICATE KEY UPDATE
        watch_duration = watch_duration + VALUES(watch_duration),
        watch_count = watch_count + 1,
        last_watch_time = NOW()
    `;

    await pool.execute(sql, [user_id, video_id, watch_duration]);

    response.json({
      code: 200,
      msg: 'success'
    });
  } catch (error) {
    console.error('记录观看历史失败:', error);
    response.json({
      code: 500,
      msg: '服务器错误'
    });
  }
}

const getComment = async (request, response) => {
  // 查询评论并关联用户信息
  const sql = `
    SELECT 
      c.*,                          -- 评论的所有信息
      u.avatar_url,                 -- 用户头像
      u.user_account as author_name    -- 用户名
    FROM video_comment c
    LEFT JOIN users u ON c.user_id = u.user_id
    WHERE c.video_id = ?
    ORDER BY c.comment_time DESC    -- 按评论时间倒序排序
  `;

  try {
    const [results] = await pool.execute(sql, [request.params.videoID]);

    // 处理返回数据
    const responseData = results.map(item => {
      return {
        ...item,
        comment_time: item.comment_time,
        avatar_url: item.avatar_url ? data_url + item.avatar_url : null, // 添加域名前缀
        author_name: item.author_name // 添加用户名
      }
    });

    response.json({
      msg: 'success',
      code: "200",
      data: responseData
    });

  } catch (error) {
    console.error('获取评论失败:', error);
    response.json({
      msg: '未知错误，联系管理员',
      code: "500",
      error: error.message
    });
  }
}

const addComment = async (request, response) => {
  try {
    const {
      video_id,    // 视频ID
      content,     // 评论内容
      parent_id    // 父评论ID（回复评论时使用，默认为0表示一级评论）
    } = request.body;

    const { user_id } = request.query; // 用户ID

    // 参数验证
    if (!video_id || !user_id || !content) {
      return response.json({
        msg: '参数不完整',
        code: "400",
        data: null
      });
    }

    // 1. 获取用户名并插入评论
    const insertCommentSql = `
      INSERT INTO video_comment 
      (video_id, user_id, comment_info, comment_userName, parent_id, comment_time, like_count, is_top)
      SELECT 
        ?,                  -- video_id
        ?,                  -- user_id
        ?,                  -- comment_info
        u.author_name,     -- comment_userName 从users表获取
        ?,                  -- parent_id
        NOW(),             -- comment_time
        0,                 -- like_count
        0                  -- is_top
      FROM users u
      WHERE u.user_id = ?  -- 匹配user_id
    `;

    const [result] = await pool.execute(insertCommentSql, [
      video_id,
      user_id,
      content,
      parent_id || 0,  // 如果没有parent_id，默认为0
      user_id          // 再次使用user_id来获取用户名
    ]);

    // 触发器更新视频的评论数

    // 2. 获取用户信息和新插入的评论详情
    const getCommentDetailSql = `
      SELECT 
        c.comment_id,
        c.video_id,
        c.user_id,
        c.comment_info,
        c.parent_id,
        c.comment_time,
        c.like_count,
        c.is_top,
        u.user_account as username,
        u.avatar_url as avatar
      FROM video_comment c
      LEFT JOIN users u ON c.user_id = u.user_id
      WHERE c.comment_id = ?
    `;

    const [commentDetails] = await pool.execute(getCommentDetailSql, [result.insertId]);

    // 处理结果
    const processedComment = {
      ...commentDetails[0],
      avatar: commentDetails[0].avatar ? data_url + commentDetails[0].avatar : null,
      create_time: new Date(commentDetails[0].comment_time).toISOString(),
      replies: [], // 新评论默认没有回复
      reply_count: 0
    };

    response.json({
      msg: 'success',
      code: "200",
      data: processedComment
    });

  } catch (error) {
    console.error('添加评论失败:', error);
    console.error('错误详情:', {
      message: error.message,
      code: error.code,
      sqlState: error.sqlState,
      sqlMessage: error.sqlMessage
    });

    response.json({
      msg: '服务器错误',
      code: "500",
      error: error.message
    });
  }
}

const addDanmaku = async (request, response) => {
  try {
    const {
      video_id,    // 视频ID
      content,     // 弹幕内容
      time_point,  // 出现时间点
      type,        // 弹幕类型（0滚动、1顶部、2底部）
      color,       // 弹幕颜色
      font_size    // 字体大小
    } = request.body;

    // 参数验证
    if (!video_id || !content || time_point === undefined) {
      return response.json({
        msg: '参数不完整',
        code: "400",
        data: null
      });
    }

    // 构建SQL
    const sql = `
      INSERT INTO video_danmaku 
      (video_id, user_id, content, time_point, type, color, font_size, create_time, ip_address, is_blocked)
      VALUES 
      (?, ?, ?, ?, ?, ?, ?, NOW(), ?, 0)
    `;

    // 获取客户端IP
    const ip = request.ip || request.connection.remoteAddress;

    // 执行插入
    const [result] = await pool.execute(sql, [
      video_id,
      1,                    // 默认用户ID为1
      content,
      time_point,
      type || 0,           // 默认为滚动弹幕
      color || '#ffffff',  // 默认白色
      font_size || 25,     // 默认字号25
      ip
    ]);

    // 返回新插入的弹幕信息
    response.json({
      msg: 'success',
      code: "200",
      data: {
        danmaku_id: result.insertId,
        video_id,
        content,
        time_point,
        type: type || 0,
        color: color || '#ffffff',
        font_size: font_size || 25,
        create_time: result.create_time,
        ip_address: ip,
        is_blocked: 0
      }
    });

  } catch (error) {
    console.error('插入弹幕失败:', error);
    response.json({
      msg: '服务器错误',
      code: "500",
      data: null
    });
  }
}

// 点赞/取消点赞接口
const toggleLike = async (request, response) => {
  try {
    const { video_id } = request.body;
    const user_id = request.query.user_id;

    // 检查是否已经点赞
    const checkSql = 'SELECT like_id FROM video_likes WHERE user_id = ? AND video_id = ?';
    const [existingLike] = await pool.execute(checkSql, [user_id, video_id]);

    if (existingLike.length > 0) {
      // 已点赞，执行取消点赞
      const deleteSql = 'DELETE FROM video_likes WHERE user_id = ? AND video_id = ?';
      await pool.execute(deleteSql, [user_id, video_id]);

      response.json({
        msg: '取消点赞成功',
        code: "200",
        data: {
          isLiked: false
        }
      });
    } else {
      // 未点赞，执行点赞
      const insertSql = 'INSERT INTO video_likes (user_id, video_id) VALUES (?, ?)';
      await pool.execute(insertSql, [user_id, video_id]);

      response.json({
        msg: '点赞成功',
        code: "200",
        data: {
          isLiked: true
        }
      });
    }
  } catch (error) {
    console.error('点赞操作失败:', error);
    response.json({
      msg: '服务器错误',
      code: "500",
      error: error.message
    });
  }
};

// 收藏/取消收藏接口
const toggleCollection = async (request, response) => {
  try {
    const { video_id } = request.body;
    const user_id = request.query.user_id;

    // 检查是否已经收藏
    const checkSql = 'SELECT collection_id FROM video_collections WHERE user_id = ? AND video_id = ?';
    const [existingCollection] = await pool.execute(checkSql, [user_id, video_id]);

    if (existingCollection.length > 0) {
      // 已收藏，执行取消收藏
      const deleteSql = 'DELETE FROM video_collections WHERE user_id = ? AND video_id = ?';
      await pool.execute(deleteSql, [user_id, video_id]);

      response.json({
        msg: '取消收藏成功',
        code: "200",
        data: {
          isCollected: false
        }
      });
    } else {
      // 未收藏，执行收藏
      const insertSql = 'INSERT INTO video_collections (user_id, video_id) VALUES (?, ?)';
      await pool.execute(insertSql, [user_id, video_id]);

      response.json({
        msg: '收藏成功',
        code: "200",
        data: {
          isCollected: true
        }
      });
    }
  } catch (error) {
    console.error('收藏操作失败:', error);
    response.json({
      msg: '服务器错误',
      code: "500",
      error: error.message
    });
  }
};

// 获取视频点赞状态
const getLikeStatus = async (request, response) => {
  try {
    const { video_id } = request.body;
    const user_id = request.query.user_id;

    const sql = 'SELECT like_id FROM video_likes WHERE user_id = ? AND video_id = ?';
    const [result] = await pool.execute(sql, [user_id, video_id]);

    response.json({
      msg: 'success',
      code: "200",
      data: {
        isLiked: result.length > 0
      }
    });
  } catch (error) {
    console.error('获取点赞状态失败:', error);
    response.json({
      msg: '服务器错误',
      code: "500",
      error: error.message
    });
  }
};

// 获取视频收藏状态
const getCollectionStatus = async (request, response) => {
  try {
    const { video_id } = request.body;
    const user_id = request.query.user_id;

    const sql = 'SELECT collection_id FROM video_collections WHERE user_id = ? AND video_id = ?';
    const [result] = await pool.execute(sql, [user_id, video_id]);

    response.json({
      msg: 'success',
      code: "200",
      data: {
        isCollected: result.length > 0
      }
    });
  } catch (error) {
    console.error('获取收藏状态失败:', error);
    response.json({
      msg: '服务器错误',
      code: "500",
      error: error.message
    });
  }
};

// 搜索视频列表
const searchVideos = async (request, response) => {
  try {
    const { page = 1, page_size = 10, searchContent = '' } = request.body;
    const offset = (page - 1) * page_size;

    // 构建基础 SQL 查询
    const sql = `
      SELECT 
        v.*,
        u.author_name,
        u.avatar_url
      FROM video_list v
      LEFT JOIN users u ON v.author_id = u.user_id
      WHERE v.status = 1
      ${searchContent ? 'AND v.video_title LIKE ?' : ''}
      ORDER BY v.video_date DESC
      LIMIT ${parseInt(page_size)} OFFSET ${parseInt(offset)}
    `;

    // 构建计数 SQL 查询
    const countSql = `
      SELECT COUNT(*) as total
      FROM video_list
      WHERE status = 1
      ${searchContent ? 'AND video_title LIKE ?' : ''}
    `;

    // 构建参数数组
    const sqlParams = searchContent ? [`%${searchContent}%`] : [];
    const countParams = searchContent ? [`%${searchContent}%`] : [];

    // 执行查询
    const [videos] = await pool.execute(sql, sqlParams);
    const [countResult] = await pool.execute(countSql, countParams);

    // 计算总页数
    const total = countResult[0].total;
    const totalPages = Math.ceil(total / page_size);

    // 处理返回数据
    response.json({
      code: "200",
      msg: "success",
      data: {
        list: videos.map(video => ({
          ...video,
          video_url: video.video_url ? data_url + video.video_url : null,
          cover_url: video.cover_url ? data_url + video.cover_url : null,
          avatar_url: video.avatar_url ? data_url + video.avatar_url : null,
          video_date: video.video_date.toLocaleString()
        })),
        pagination: {
          current: parseInt(page),
          page_size: parseInt(page_size),
          total: total,
          total_pages: totalPages  // 新增总页数字段
        }
      }
    });

  } catch (error) {
    console.error('搜索视频失败:', error);
    response.json({
      code: "500",
      msg: "服务器错误",
      error: error.message
    });
  }
};

// 分享视频接口
const shareVideo = async (request, response) => {
  try {
    const { video_id } = request.body;
    
    if (!video_id) {
      return response.json({
        code: 400,
        msg: '缺少必要参数',
        data: null
      });
    }

    // 更新视频转发数
    const sql = `
      UPDATE video_list 
      SET forward_num = forward_num + 1 
      WHERE video_id = ?
    `;

    await pool.execute(sql, [video_id]);

    response.json({
      code: 200,
      msg: '分享成功',
      data: null
    });
  } catch (error) {
    console.error('分享视频失败:', error);
    response.json({
      code: 500,
      msg: '服务器错误',
      error: error.message
    });
  }
};

// 获取指定用户发布的视频列表
const getUserVideos = async (request, response) => {
  try {
    const user_id = request.query.user_id;
    const { page = 1, page_size = 10 } = request.body;
    
    if (!user_id) {
      return response.json({
        code: "400",
        msg: "缺少必要参数 user_id"
      });
    }

    const offset = (page - 1) * page_size;

    // 构建基础 SQL 查询
    const sql = `
      SELECT 
        v.*,
        u.author_name,
        u.avatar_url
      FROM video_list v
      LEFT JOIN users u ON v.author_id = u.user_id
      WHERE v.status = 1 AND v.author_id = ?
      ORDER BY v.video_date DESC
      LIMIT ${parseInt(page_size)} OFFSET ${parseInt(offset)}
    `;

    // 构建计数 SQL 查询
    const countSql = `
      SELECT COUNT(*) as total
      FROM video_list
      WHERE status = 1 AND author_id = ?
    `;

    // 执行查询
    const [videos] = await pool.execute(sql, [user_id]);
    const [countResult] = await pool.execute(countSql, [user_id]);

    // 计算总页数
    const total = countResult[0].total;
    const totalPages = Math.ceil(total / page_size);

    // 处理返回数据
    response.json({
      code: "200",
      msg: "success",
      data: {
        list: videos.map(video => ({
          ...video,
          video_url: video.video_url ? data_url + video.video_url : null,
          cover_url: video.cover_url ? data_url + video.cover_url : null,
          avatar_url: video.avatar_url ? data_url + video.avatar_url : null,
          video_date: video.video_date.toLocaleString()
        })),
        pagination: {
          current: parseInt(page),
          page_size: parseInt(page_size),
          total: total,
          total_pages: totalPages
        }
      }
    });

  } catch (error) {
    console.error('获取用户视频失败:', error);
    response.json({
      code: "500",
      msg: "服务器错误",
      error: error.message
    });
  }
};

module.exports = {
  getVideoList,
  recordHistory,
  getComment,
  addComment,
  addDanmaku,
  toggleLike,
  toggleCollection,
  getLikeStatus,
  getCollectionStatus,
  searchVideos,
  shareVideo,
  getUserVideos
};